package geldautomat;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;

import mware_lib.NameService;
import mware_lib.ObjectBroker;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JSeparator;

import cash_access.Account;
import cash_access.OverdraftException;

/**
 * Geldautomat:
 * GUI to access an account from a given bank.
 * @author Rico Flaegel
 * @author Jan Quenzel
 */
public class Geldautomat extends JFrame {
	private static final long serialVersionUID = -2213777210234648106L;
	private JPanel contentPane;
	private JTextField textField_accID;
	private JTextField textField_balance;
	private JTextField textField_sum;
	private JTextField txtLocalhost;
	private JTextField textField_port;
	private String oldHostName = "";
	private String oldPort = "";
	private String oldAccID = "";
	/**
	 * @uml.property  name="act_acc"
	 * @uml.associationEnd  
	 */
	private Account act_acc;

	/**
	 * Launch the application.
	 */
	public static void main(final String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				String hostName = null;
				int bankPort = 0;
				try {
					if(args.length == 2){
						hostName = args[0];
						try{
							bankPort = Integer.parseInt(args[1]);
						}catch(NumberFormatException e){
							System.out.println("port is not valid");
							return;
						}
						Geldautomat frame = new Geldautomat(hostName, bankPort);
						frame.setVisible(true);
						
					}else if(args.length != 2 ){
						System.out.println("usage: Geldautomat HOSTNAME PORT");
					}
					

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public Geldautomat(String hostName, int bankPort){
		this();
		txtLocalhost.setText(hostName);
		txtLocalhost.setEditable(false);
		textField_port.setText(bankPort+"");
		textField_port.setEditable(false);
	}
	
	/**
	 * Create the frame.
	 */
	public Geldautomat() {
		setTitle("Geldautomat-Applikation");
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 653, 469);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		textField_accID = new JTextField();
		textField_accID.setBounds(87, 80, 179, 20);
		contentPane.add(textField_accID);
		textField_accID.setColumns(10);
		
		JLabel lblKontonummer = new JLabel("Kontonummer");
		lblKontonummer.setBounds(10, 83, 90, 14);
		contentPane.add(lblKontonummer);
		
		textField_balance = new JTextField();
		textField_balance.setEditable(false);
		textField_balance.setBounds(87, 105, 175, 20);
		contentPane.add(textField_balance);
		textField_balance.setColumns(10);
		
		JButton btnGetBalance = new JButton("Kontostand abfragen");
		btnGetBalance.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				getBalance();
			}
		});
		btnGetBalance.setBounds(277, 104, 168, 23);
		contentPane.add(btnGetBalance);
		
		JLabel lblBetrag = new JLabel("Betrag");
		lblBetrag.setBounds(10, 188, 46, 14);
		contentPane.add(lblBetrag);
		
		textField_sum = new JTextField();
		textField_sum.setBounds(90, 185, 86, 20);
		contentPane.add(textField_sum);
		textField_sum.setColumns(10);
		
		JButton btnDeposit = new JButton("einzahlen");
		btnDeposit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				einzahlen(false);
			}
		});
		btnDeposit.setBounds(191, 184, 89, 23);
		contentPane.add(btnDeposit);
		
		JButton btnAuszahlen = new JButton("auszahlen");
		btnAuszahlen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				auszahlen();
			}
		});
		btnAuszahlen.setBounds(424, 184, 89, 23);
		contentPane.add(btnAuszahlen);
		
		JButton btnxEinzahlen = new JButton("2000x einzahlen");
		btnxEinzahlen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				einzahlen(true);
			}
		});
		btnxEinzahlen.setBounds(290, 184, 124, 23);
		contentPane.add(btnxEinzahlen);
		
		JLabel lblBankhostname = new JLabel("Bankhostname");
		lblBankhostname.setBounds(10, 11, 90, 14);
		contentPane.add(lblBankhostname);
		
		txtLocalhost = new JTextField();
		txtLocalhost.setText("localhost");
		txtLocalhost.setBounds(101, 8, 86, 20);
		contentPane.add(txtLocalhost);
		txtLocalhost.setColumns(10);
		
		JLabel lblPort = new JLabel("Port");
		lblPort.setBounds(207, 11, 46, 14);
		contentPane.add(lblPort);
		
		textField_port = new JTextField();
		textField_port.setText("2000");
		textField_port.setBounds(242, 8, 86, 20);
		contentPane.add(textField_port);
		textField_port.setColumns(10);
		
		JSeparator separator = new JSeparator();
		separator.setBounds(10, 32, 617, 2);
		contentPane.add(separator);
	}
	
	/**
	 * tries to withdraw the entered amount of money from the entered account number
	 */
	private void auszahlen(){
		Account acc = getAccount();
		
		double sum = getSum();
		
		if(acc != null){
			try {
				acc.withdraw(sum);
				
			} catch (OverdraftException e1) {
				JOptionPane.showMessageDialog(null,"Konto wuerde mit diesem Betrag ueberzogen werden, Aktion abgebrochen!","Fehler", JOptionPane.ERROR_MESSAGE);
			}catch(Exception e){
				if(e instanceof OverdraftException) System.out.println("BUH!");
				e.printStackTrace();
			}
		}else{
			JOptionPane.showMessageDialog(null,"Konto nicht gefunden!","Fehler", JOptionPane.ERROR_MESSAGE);
			textField_balance.setText("");
		}
		
	}
	
	/**
	 * tries to deposit the given amount of money to the given account
	 * @param multipleTimes if true does it 2000 times in a row
	 */
	private void einzahlen(boolean multipleTimes){
		Account acc = getAccount();
		
		double sum = getSum();
		
		if(acc != null){
			int numberOfTimes = (multipleTimes?2000:1);
			for (int i = 0; i < numberOfTimes; i++) {
				acc.deposit(sum);
			}		
		}else{
			JOptionPane.showMessageDialog(null,"Konto nicht gefunden!","Fehler", JOptionPane.ERROR_MESSAGE);
		}	
	}
	
	/**
	 * tries to get the balance of the given account
	 */
	private void getBalance(){
		Account acc = getAccount();
		if(acc != null){
			double sum = acc.getBalance();
			textField_balance.setText(sum+"�");
		}else{
			JOptionPane.showMessageDialog(null,"Konto nicht gefunden!","Fehler", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	/**
	 * Tries to get the sum from the GUI. It must be a number and all decimal numbers trailing the second decimal number will be cut off.
	 * @return the correct sum from the gui
	 */
	private double getSum(){
		double sum = 0;
		try{
			sum = Double.parseDouble(textField_sum.getText());
			int m = (int) sum;
			double diff = ((int) ((sum-m)*100))/100.0;
			sum = m+diff;
		}catch(NumberFormatException e2){
			JOptionPane.showMessageDialog(null,"die angegebene Summe ist kein gueltiger Geldbetrag!","Fehler", JOptionPane.ERROR_MESSAGE);
		}
		return sum;
	}
	
	/**
	 * Get the AccountStub from the NameService matching the kontonummer from the GUI.
	 * @return the AccountStub for the wanted Account
	 */
	private Account getAccount(){
		if(oldAccID != textField_accID.getText() && oldHostName != txtLocalhost.getText() && oldPort != textField_port.getText()){
			String hostname = txtLocalhost.getText();
			String port = textField_port.getText();
			int port_i = 0;
			try{
				port_i = Integer.parseInt(port);
			}catch(NumberFormatException ne){
				JOptionPane.showMessageDialog(null,"der angegebene Port ist keine Ganzzahl!","Fehler", JOptionPane.ERROR_MESSAGE);
				return null;
			}
			
			ObjectBroker brk = ObjectBroker.getBroker(hostname, port_i);
			NameService ns = brk.getNameService();
			
			return (Account)ns.resolve(textField_accID.getText());
		}else{
			return act_acc;
		}
		
	}

}
